import std.random;
import std.stdio: writefln;
import std.math: abs;

public class Perceptron {
	int theta;
	int[] wagi;
	bool trained = false;

    int bestAge = 0;
    private int currAge = 0;
    private int[] bestWagi;

	this(int size){
		wagi.length = size;
		for(int i = 0; i < size; i++)
			while(!wagi[i])
				wagi[i] = (rand() % 10) - 5;
		theta = (rand() % 10) - 5;
		bestWagi.length = size;
	}
	
	int detect(int[] input){
		int val = 0;
		for(int i = 0; i < input.length; i++)
			val += wagi[i] * input[i];
		
		if(val > theta) return 1;
		else if(val < theta) return -1;
		else return 0;
	}

    int detect2(int[] input, out float wsp){
        int val = 0;

        for(int i = 0; i < input.length; i++)
            val += wagi[i] * input[i];

       if(theta)
            wsp = abs((val - theta)/theta);
        else
            wsp = 0;

        if(val > theta) return 1;
        else if(val < theta) return -1;
        else return 0;
    }


	void train(int[] input, int expect){
			
		int eval = detect(input);
		if(eval != expect){
			currAge = 0;
			theta -= expect;
			foreach(a,inout b; wagi)
				 b += (input[a] * expect);
		}
		else{
			currAge++;
			if(currAge > bestAge){
				bestAge = currAge;
				bestWagi[] = wagi[];
			}
		}
	}

	void endTraining(){
		trained = true;
		wagi[] = bestWagi[];
	}
}
